﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Infragistics.Win.UltraWinGrid;

namespace lipesin.Main.Category
{
	public partial class CategorySelector : Form
	{
		DataTable _categorySource;
		CategoryType _type = CategoryType.Expence;
		//long? CurrentCategoryId = null;
		public long? CurrentCategoryId { get; private set; }

		public CategorySelector()
		{
			InitializeComponent();
		}

		private long? ParentId
		{
			get
			{
				if (!CurrentCategoryId.HasValue) return null;
				DataRow[] selected = _categorySource.Select("id = {0}".F(CurrentCategoryId));
				if (selected.Length > 0 && !Convert.IsDBNull(selected[0]["parent_id"])) return (long)selected[0]["parent_id"];
				return null;
			}
		}

		private long? SelectedId
		{
			get
			{
				long id = (long)SelectedRow["id"];
				if (id > 0) return id;
				return null;
			}
		}

		private DataRow SelectedRow
		{
			get
			{
				Infragistics.Win.UltraWinGrid.UltraGridRow crow = grdCategories.ActiveRow;
				DataRowView crowv = crow.ListObject as DataRowView;
				return crowv.Row;
			}
		}

		public void Init(CategoryType type, long? currentCategoryId)
		{
			_type = type;
			CurrentCategoryId = currentCategoryId;
		}

		private void CategorySelector_Load(object sender, EventArgs e)
		{
			Reload();
		}

		private void Reload()
		{
			//StringBuilder where = new StringBuilder();
			//where.AppendFormat("type = {0}", (int)_type);
			//if (!chkHistory.Checked)
			//    where.Append(" date_from < getdate() and date_to is null");
			string select = @"
				select 
					cat.*
					, (select count(*) from category cat2 where cat2.parent_id = cat.id) childs 
				from category cat";
			//if (where.Length > 0) select += " where " + where.ToString();
			_categorySource = Dalc.ExecuteToDataTable(select);
			_categorySource.Columns.Add("visible", typeof(bool));
			DataRow goBack = _categorySource.NewRow();
			_categorySource.Rows.Add(goBack);
			goBack["id"] = 0;
			goBack["parent_id"] = 0;
			goBack["order"] = 0;
			goBack["childs"] = 0;
			goBack["type"] = (int)_type;
			goBack["name"] = @"..";
			goBack["date_from"] = DateTime.MinValue;
			DisplayCurrentCategory();
		}

		private void DisplayCurrentCategory()
		{
			foreach (DataRow row in _categorySource.Rows) row["visible"] = false;
			StringBuilder where = new StringBuilder();
			if (ParentId.HasValue)
			{
				where.AppendFormat("parent_id = {0} and type is null", ParentId);
				_categorySource.Select("id = 0")[0]["visible"] = true;
			}
			else
				where.AppendFormat("parent_id is null and type = {0}", (int)_type);
			if (!chkHistory.Checked)
				where.Append(@" and date_from <= #{0:MM.dd.yyyy}# and (date_to is null or date_to >= #{0:MM.dd.yyyy}#)".F(DateTime.Today));
			_categorySource.Select(where.ToString()).All(row => { row["visible"] = true; return true; });

			DataView view = new DataView(_categorySource, "visible", "order", DataViewRowState.CurrentRows);
			grdCategories.DataSource = view;
			if (CurrentCategoryId.HasValue)
			{
				foreach (Infragistics.Win.UltraWinGrid.UltraGridRow grow in grdCategories.Rows)
					if ((long)((grow.ListObject as DataRowView)["id"]) == CurrentCategoryId.Value) grow.Activate();
			}
			grdCategories.Select();
		}

		private void CategorySelector_KeyDown(object sender, KeyEventArgs e)
		{
			switch (e.KeyData)
			{
				case Keys.Back:
				case Keys.Left:
					if (ParentId != null)
					{
						CurrentCategoryId = ParentId;
						DisplayCurrentCategory();
					}
					e.Handled = true;
					break;
				case Keys.Right:
				case Keys.Enter:
					DataRow row = SelectedRow;
					if (row != null)
					{
						if ((int)row["childs"] > 0)
						{
							DataView view = new DataView(_categorySource, "parent_id = {0}".F(SelectedId), "order", DataViewRowState.CurrentRows);
							CurrentCategoryId = (long)(view.ToTable().Rows[0]["id"]);
							DisplayCurrentCategory();
						}
						else if (e.KeyData == Keys.Enter)
							if ((long)row["id"] == 0)
							{
								CurrentCategoryId = ParentId;
								DisplayCurrentCategory();
							}
							else Close();

					}
					e.Handled = true;
					break;
				case Keys.Enter | Keys.Control:
					Close();
					e.Handled = true;
					break;
			}
		}

		private void chkHistory_CheckedChanged(object sender, EventArgs e)
		{
			DisplayCurrentCategory();
		}

		private void btnUp_Click(object sender, EventArgs e)
		{
			ChangeOrder(Infragistics.Win.UltraWinGrid.SiblingRow.Previous);
		}

		private void btnDown_Click(object sender, EventArgs e)
		{
			ChangeOrder(Infragistics.Win.UltraWinGrid.SiblingRow.Next);
		}

		private void ChangeOrder(Infragistics.Win.UltraWinGrid.SiblingRow fromRow)
		{
			grdCategories.Select();
			if (grdCategories.ActiveRow == null) return;
			Infragistics.Win.UltraWinGrid.UltraGridRow crow = grdCategories.ActiveRow;
			Infragistics.Win.UltraWinGrid.UltraGridRow srow = grdCategories.ActiveRow.GetSibling(fromRow);
			if (srow == null) return;
			DataRowView crowv = crow.ListObject as DataRowView;
			DataRowView srowv = srow.ListObject as DataRowView;
			if ((int)srowv["order"] == 0 || (int)crowv["order"] == 0) return;
			int order = (int)srowv["order"];
			srowv["order"] = crowv["order"];
			crowv["order"] = order;
			grdCategories.DataBind();
		}

		private void btnAdd_Click(object sender, EventArgs e)
		{
			CategoryEditor editor = new CategoryEditor();
			long? id = editor.EditCategory(this, _type, ParentId, null);
			if (id.HasValue)
			{
				CurrentCategoryId = id;
				Reload();
			}
		}

		private void btnEdit_Click(object sender, EventArgs e)
		{
			if (!SelectedId.HasValue) return;
			CategoryEditor editor = new CategoryEditor();
			long? id = editor.EditCategory(this, _type, ParentId, SelectedId);
			if (id.HasValue)
			{
				CurrentCategoryId = id;
				Reload();
			}
		}

		private void btnRemove_Click(object sender, EventArgs e)
		{
			if (!SelectedId.HasValue) return;
			if (MessageBox.Show(this, "Удалить категорию '{0}'?".F(SelectedRow["name"]), "Удаление", MessageBoxButtons.OKCancel) != System.Windows.Forms.DialogResult.OK) return;
			string sql = @"
				with req(id) as
				(
					select id from category where id = {0}
					union all
					select c.id
					from req r
					join category c on c.parent_id = r.id
				)
				update category set date_to = getdate() where id in (select * from req);";
			CurrentCategoryId = SelectedId;
			Dalc.ExecuteNonQuery(sql.F(SelectedId));
			Reload();
		}

		private void grdCategories_Leave(object sender, EventArgs e)
		{
			CurrentCategoryId = SelectedId;
		}

		private void grdCategories_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
		{
			var columns = grdCategories.DisplayLayout.Bands[0].Columns;
			foreach (UltraGridColumn c in columns) c.Hidden = true;
			UltraGridColumn column;
			column = columns["name"];
			column.Hidden = false;
			column.Header.Caption = "Наименование категории";
			column = columns["date_from"];
			column.Hidden = false;
			column.Header.Caption = "Создана";
			column = columns["date_to"];
			column.Hidden = !chkHistory.Checked;
			column.Header.Caption = "Удалена";

		}
	}
}
